

#include <string.h>
#include <stdbool.h>
#include "usb_device.h"
#include "sys_manager.h"
#include "drv_usart.h"
#include "drv_pwm.h"
#include "drv_adc.h"
#include "nst_log.h"
#include "app_main.h"
#include "app_button.h"
#include "app_misc.h"
#include "app_msg.h"
#include "app_midi.h"
#include "app_sys.h"
#include "app_pwr.h"
#include "app_led.h"
#include "app_flash_config.h"
#include "drv_watchdog.h"

#define INTERVAL_MS 250 // 间隔时间, 250ms

extern PedalControl taban_pedals[2];

bool app_tra_key_stop_signal = false; // 停止信号标志
bool app_tra_disable = false;
uint8_t app_tra_countdown_ended = 0;

bool solenoid_force_setting_mode = false; // 力度设定模式标志




void app_pwr_off()
{
    // 分段延时，每段喂狗避免看门狗超时
    for(int i = 0; i < 10; i++)
    {
        HAL_Delay(100);
#if (WATCHDOG_ENABLE == 1)
        drv_watchdog_refresh();
#endif
    }
}


#define PEDAL_NUM 8
#define NOTE_NUM 5
void app_tra_key_test()
{
    uint8_t note_on_base = 0x15; // 起始音符
    uint8_t note_end = 0x6C;
    uint8_t velocity = 0x4B;     // 力度
    uint8_t control_value = 0x3F;

//    uint8_t cur_note_on;
    uint8_t cur_note_off = 0;

    uint8_t count = 0;
    uint8_t max_count = 88 + NOTE_NUM - 1;
    uint8_t pedal_ind = 0;
    uint8_t note_ind = 0;

    uint8_t data[9]; // 数据缓冲区
    uint8_t data_len = 0;

    app_tra_disable = false;
    app_tra_key_stop_signal = false;

    while (!app_tra_disable) 
    {
#if (WATCHDOG_ENABLE == 1)
        drv_watchdog_refresh(); // 长循环中定期喂狗
#endif
        
        // if(app_tra_key_stop_signal) //停止逐渐测试
        // {
        //     break;
        // }

        if(count==0)
        {
            data[0] = 0xB0;
            data[1] = 0x40;
            data[2] = 0x3F;
            data[3] = 0x90;  
            data[4] = 0x15;
            data[5] = 0x4B;
            data_len = 6;
            app_sync_data(SRC_TRA_TEST, data, data_len);
            app_midi_handle_msg(&data[0]);  // 处理踏板开关状态
            delay_ms(240);

            // 重置数据
            memset(data, 0, sizeof(data));
            data_len = 0;
            count++;
            continue;
        }
     
        // 清除数据缓冲区
        memset(data, 0, sizeof(data));
        data_len = 0;
        
        //note on
        if(count < 88)
        {
            note_ind = count % 88;
            data[data_len++] = 0x90;
            data[data_len++] = note_on_base + note_ind; 
            data[data_len++] = velocity;
        }
        else // note off
        {
            note_ind = (count - 88) % 88;
            cur_note_off = (note_end - NOTE_NUM + 1) + note_ind;
            data[data_len++] = 0x80;
            data[data_len++] = cur_note_off;
            data[data_len++] = 0x00;
        }
        
        // 发送延迟的Note Off（仅在第一轮且超过NOTE_NUM步时）
        if(count >= NOTE_NUM && count < 88)
        {
            uint8_t off_note_ind = (count - NOTE_NUM) % 88;
            cur_note_off = note_on_base + off_note_ind;
            data[data_len++] = 0x80;
            data[data_len++] = cur_note_off;
            data[data_len++] = 0x00;
        }


        if(count%PEDAL_NUM == 0)
        {
            pedal_ind = count/PEDAL_NUM;
            data[data_len++] = 0xB0;
            
            switch (pedal_ind%4)
            {
            case 0:
                data[data_len++] = 0x40; 
                data[data_len++] = control_value;
                break;
            case 1:
                data[data_len++] = 0x43; 
                data[data_len++] = control_value;
                break;
            case 2:
                data[data_len++] = 0x40; 
                data[data_len++] = 0x00;
                break;
            case 3:
                data[data_len++] = 0x43; 
                data[data_len++] = 0x00;
                break;
            default:
                break;
            }

            app_midi_handle_msg(&data[data_len - 3]); // 处理踏板开关状态
        }

        app_sync_data(SRC_TRA_TEST, data, data_len);
        
#if (WATCHDOG_ENABLE == 1)
        drv_watchdog_refresh(); // 延时前再次喂狗
#endif
        delay_ms(240);

        data_len = 0;

        if(count == max_count)
        {
            count = 0;
            if(app_tra_key_stop_signal)
            {
                break;
            }
            continue;
        }
        count++;
    }
}


void app_tra_key_test_stop()
{
    app_tra_key_stop_signal = true;
}


void app_sys_status_handle()
{
    // 检查各串口错误状态，如果都正常则清除全局错误标志
    if(system_status.error & SYS_ERROR_UART)
    {
        // 如果所有串口错误计数都较低，则清除全局UART错误标志
        if(system_status.uart.uart1_error_count <= 3 && 
           system_status.uart.uart2_error_count <= 3 && 
           system_status.uart.uart3_error_count <= 3)
        {
            system_status.error &= ~SYS_ERROR_UART;  // 清除UART错误标志
        }
    }
    
    if(system_status.error)
    {
#if (UART_ERROR_MONITORING_ENABLE == 1)
        app_led_set_state(APP_LED_STATE_ERROR);
#endif
        system_status.wait_error_recover = 1;
    }
    else
    {
        // 错误恢复后清除等待恢复标志
        if(system_status.wait_error_recover)
        {
            system_status.wait_error_recover = 0;
        }
        
        if(pwr_state == PWR_ON)
        {
            app_led_set_state(APP_LED_STATE_NORMAL);
        }
        else
        {
            app_led_set_state(APP_LED_STATE_STANDBY);
        }
    }
}

void app_pwr_status_handle()
{
    if(system_status.power.pending_switch)
    {
        system_status.power.pending_switch = 0;
        app_handle_pwr_switch_info_output();
    }
}

void app_init()
{
    app_sys_init();
    drv_usart_init();
    drv_pwm_init(22000);    //22kHz
    // app_button_init();
    app_msg_init();
    drv_adc_init();
    app_led_init();

    // 新增：Flash配置初始化
    app_flash_config_init();
    
    app_taban_apply_flash_params(); // 从Flash应用踏板力度参数
    
#if (WATCHDOG_ENABLE == 1)
    // 看门狗初始化
    drv_watchdog_init();
#endif
}


void app_main()
{
    APP_LOG_PRINT(APP_USB_DEVICE_NAME);
    delay_ms(100);
    APP_LOG_PRINT("app main entry!!!");
    delay_ms(100);
    
    app_msg_t *midi_msg = NULL;
    app_msg_t *uart_rx_msg = NULL;
    work_flag = WORK_PWR_OFF;
    
    while (1)
    { 
#if (WATCHDOG_ENABLE == 1)
        drv_watchdog_feed_with_counter(); // 主循环喂狗
#endif
        
        app_sys_status_handle();
        app_pwr_status_handle();
        
        switch (work_flag)
        {
        case WORK_INIT:
            {
                // app_handle_pwr_switch_info_output();
            }
            break;
        case WORK_PWR_ON:
        case WORK_SOLENOID_FORCE_SETTING_MODE:
            {
                // 处理 UART RX 消息队列
                if (!app_msg_is_empty(&uart_rx_queue))
                {
                    if (app_msg_dequeue(&uart_rx_queue, &uart_rx_msg))
                    {
                        // 注意：原来的 uart_rx_msg.src_port 和 uart_rx_msg.data_len 改为 uart_rx_msg->tp.port 和 uart_rx_msg->len
                        app_sync_data((MessageSource)uart_rx_msg->tp.port, uart_rx_msg->data, uart_rx_msg->len);
                        app_msg_process_midi_data(uart_rx_msg->data, uart_rx_msg->len);
                        // 使用完后释放消息对象
                        app_msg_free(uart_rx_msg);
                    }
                }

                // 处理 UART TX 消息队列
                app_handle_tx_queue();

                // 每次循环检查队列并处理一条 MIDI 消息
                if (!app_msg_is_empty(&midi_queue))
                {
                    if (app_msg_dequeue(&midi_queue, &midi_msg))
                    {
                        if(work_flag == WORK_PWR_ON)
                        {
                            // 根据消息内容判断处理不同的 MIDI 指令
                            if (midi_msg->data[0] == 0xB0 && midi_msg->data[1] == 0x03 && midi_msg->data[2] == 0x7F)
                            {
                                // 执行电源开逻辑
                            }
                            else if (midi_msg->data[0] == 0xB0 && midi_msg->data[1] == 0x03 && midi_msg->data[2] == 0x00)
                            {
                                if(is_power_on())
                                {
                                    app_power_off();     // 关机
                                }
                            }
                            else if (midi_msg->data[0] == 0xB0 && midi_msg->data[1] == 0x0E && midi_msg->data[2] == 0x7F)
                            {
                                work_flag = WORK_SOLENOID_FORCE_SETTING_MODE; // 进入电磁铁力度设定模式
                            }
                            else
                            {
                                app_midi_handle_msg(midi_msg->data);
                            }
                        }
                        else if(work_flag == WORK_SOLENOID_FORCE_SETTING_MODE)
                        {
                            if (!solenoid_force_setting_mode)
                            {
                                solenoid_force_setting_mode = true;
                                app_buzzer_trigger(APP_BUZZER_TRA_TEST_DURATION_MS); // 蜂鸣器提示进入模式
                            }

                            if (midi_msg->data[0] == 0xB0 && midi_msg->data[1] == 0x0E && midi_msg->data[2] == 0x00)
                            {
                                // 退出力度设定模式
                                solenoid_force_setting_mode = false;
                                // 保存到Flash
                                app_midi_flash_save_solenoid_durations();
                                work_flag = WORK_PWR_ON;
                            }
                            else
                            {
                                // 在力度设定模式下，应用力度值到电磁铁参数
                                app_midi_handle_msg_force_setting(midi_msg->data);
                            }
                        }       

                        // 处理完后释放消息
                        app_msg_free(midi_msg);
                    }
                }
                

                // if(taban_pedals[0].state!=TABAN_STATE_OFF)
                // {
                //     app_taban_switch_state(0);
                // }

                // if(taban_pedals[1].state!=TABAN_STATE_OFF)
                // {
                //     app_taban_switch_state(1);
                // }
      
            }
            break;
        case WORK_PWR_OFF:
            { 
                APP_LOG_TIMESTAMP_PRINT();
                app_pwr_off();
            }
			break;
        case WORK_TRA_KEY_TEST_MODE:
            {
                app_buzzer_trigger(APP_BUZZER_TRA_TEST_DURATION_MS);

                if(system_status.uart.uart1_dma_tx_busy == 1)
                {
                    system_status.uart.uart1_dma_tx_busy = 0;
                }

#if (WATCHDOG_ENABLE == 1)
                drv_watchdog_refresh(); // 进入长时间处理前喂狗
#endif
                app_tra_key_test();
                work_flag = WORK_PWR_ON;
            }
			break;
        default:
            break;
        }
    } 
}



